#include "action_http.h"
#include "context.h"
#include "util.h"
#include "Md5.h"
#include "json.h"


static bool __init__ = ActionHttp::Init();

inline void ResponseHttp(std::uint32_t request_id, int err, const std::string& body)
{
    Json::Value json;
    json["err_code"] = err;
    json["Data"] = body;
    std::map<std::string,std::string> heads;
    heads["Content-Type"] = "application/json";
    std::string data = CTools::ToStr(json);
    log_debug("request_id:%d,data:%s", request_id, data.c_str());
    g_Ctx.msg_router.httpServerBack(request_id, 200, heads, data);
}

bool ActionHttp::Init()
{
    g_Ctx.msg_router.BindHttpHandle("post", "/log/update_level", ActionHttp::HandleLoglvl);
    g_Ctx.msg_router.BindHttpHandle("post", "/srvmanage/retire", ActionHttp::HandleServerRetire);

    return true;
}

void ActionHttp::HandleCommon(HttpData&& http_data)
{
    log_debug(" request_id=%d method=%s target=%s body_length=%d", 
        http_data.request_id, http_data.method.c_str(), http_data.target.c_str(), http_data.body.length());

    NETInputPacket input;
    input.Copy(http_data.body.c_str(), http_data.body.length());
    g_Ctx.host->m_pGame->SendToSrvNew(&input);

    Json::FastWriter writer;
    Json::Value respRoot;
    respRoot["receive"] = true;
    respRoot["timestamp"] = (uint32)time(NULL);

    int status_code = 200;
    std::string respBody = writer.write(respRoot);
    std::map<std::string, std::string> headers;
    headers["Content-Type"] = "text/plain";
    HiveNS::MainWorker::getInstance()->sendBackToRequest(http_data.request_id, status_code, respBody, headers);
}

void ActionHttp::HandleLoglvl(HttpData&& http_data)
{
    int err = 0;
    std::string body = "";
    do
    {
        Json::Value http_req_json;
        if (!CTools::FromStr(http_req_json, http_data.body))
        {
            log_error("json parser failed, url:%s, body:%s", http_data.target.c_str(), http_data.body.c_str());
            err = 1;
            break;
        }

		std::int32_t sv_type = http_req_json["server_type"].asInt();
		std::int32_t svid =  http_req_json["server_id"].asInt();
		std::int32_t lvl =  http_req_json["level"].asInt();
		
		log_info("sv_type:%d,svid:%d,lvl:%d", sv_type, svid, lvl);
		if (sv_type == 0) 
		{
			body = "server_type not exist";
			break;
		}
		if (lvl == 0)
		{
			body = "level not exist";
			break;
		}

		NETOutputPacket push;
		push.Begin(SET_LOG_LEVEL);
		push.WriteInt(lvl);
		push.End();
        
        // todo 是否可调整为走dispatch转发，无需在master加配置
		if (svid == 0)
		{
            g_Ctx.host->BroadcastMessageDirect(&push, sv_type);
		}
		else
		{
			g_Ctx.host->SendPacket( &push, sv_type, svid);
		}

        body = "ok";
    } while (false);
    ResponseHttp(http_data.request_id, err, body);
}

// 服务退休
void ActionHttp::HandleServerRetire(HttpData&& http_data)
{
    int err = 0;
    std::string body = "";
    do
    {
        Json::Value http_req_json;
        if (!CTools::FromStr(http_req_json, http_data.body))
        {
            log_error("json parser failed, url:%s, body:%s", http_data.target.c_str(), http_data.body.c_str());
            err = 1;
            break;
        }

        if (!http_req_json.isMember("server_type") || !http_req_json["server_type"].isInt())
        {
			body = "server_type err";
            err = 2;
            break;
        }
        if (!http_req_json.isMember("server_id") || !http_req_json["server_id"].isInt())
        {
			body = "server_id err";
            err = 3;
            break;
        }

		std::int32_t sv_type = http_req_json["server_type"].asInt();
		std::int32_t svid =  http_req_json["server_id"].asInt();
		
		log_info("sv_type:%d,svid:%d", sv_type, svid);
		if (sv_type == 0) 
		{
			body = "server_type not exist";
            err = 4;
			break;
		}
		if (svid == 0)
		{
			body = "svid not exist";
            err = 5;
			break;
		}

		NETOutputPacket push;
		push.Begin(SERVICEMANAGER_SRV_RETIRE_SERVICE);
		push.WriteInt(sv_type);
		push.WriteInt(svid);
		push.End();
        
        g_Ctx.host->SendPacket(&push, SERVER_TYPE_SERVICE_MANAGER);

        body = "ok";
    } while (false);
    ResponseHttp(http_data.request_id, err, body);
}





















